package br.ufsc.aps.convocados;

import br.ufsc.inf.leobr.cliente.Jogada;
import br.ufsc.inf.leobr.cliente.exception.ArquivoMultiplayerException;
import br.ufsc.inf.leobr.cliente.exception.JahConectadoException;
import br.ufsc.inf.leobr.cliente.exception.NaoConectadoException;
import br.ufsc.inf.leobr.cliente.exception.NaoPossivelConectarException;
import javax.swing.JOptionPane;

public class AtorJogador {

    private PanelConnect connectPanel;
    private PanelTabuleiro tabuleiroPanel;
    private Tabuleiro meuTabuleiro;
    protected AtorNetGames rede;
    protected String nomeUsuario;
    private boolean isConectado = false;
    private boolean jogoTerminado = false;


    public void setJogoTerminado(boolean jogoTerminado) {
        this.jogoTerminado = jogoTerminado;
    }
   

    public void setIsConectado(boolean isConectado) {
        this.isConectado = isConectado;
    }

    public boolean isConectado() {
        return isConectado;
    }

    public AtorJogador() {
        rede = new AtorNetGames(this);
        meuTabuleiro = new Tabuleiro();
    }

    public String getNome() {
        return nomeUsuario;
    }

    public void setNome(String nome) {
        this.nomeUsuario = nome;
    }

    public String obterDadosConexao() {
        return "venus.inf.ufsc.br";
    }

    public boolean conectar() throws JahConectadoException, NaoPossivelConectarException, ArquivoMultiplayerException {
        String servidor;
        servidor = obterDadosConexao();
        boolean exito = rede.conectar(servidor, nomeUsuario);
        if (exito) {
            setIsConectado(exito);
        }
        return exito;
    }

    public void finalizarPartida() {
        rede.desconectar();
        meuTabuleiro.reset();
    }

    public void desconectar() {
        if (isConectado()) {
            rede.desconectar();
            setIsConectado(false);
        }
    }

    public void iniciarPartida() throws NaoConectadoException {
        if (isConectado()) {
            rede.iniciarPartida();
            setJogoTerminado(false);                        
        } else {
            throw new NaoConectadoException();
        }
    }

//    public int reiniciarPartida() {
//        boolean emAndamento = false;//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<,
//        if (emAndamento) {
//            rede.reiniciarPartida();
//            
//            return 15;
//        } else {
//            return 8;
//        }
//
//    }
    public void tratarInicioPartida(Integer ordem) {
        connectPanel.waitFinished();
        String nomeOponente = rede.informarNomeAdversario(nomeUsuario);
        meuTabuleiro.criarTecnicos(nomeUsuario, nomeOponente);
        meuTabuleiro.resetAndOrder(ordem);
        tabuleiroPanel.montar();
        if (ordem == 1) {
            this.enviarJogadaDeInico(false);
        }

    }

//    public ImagemMap informarEstado() {
//        ImagemMap estado = map.informarEstado();
//        return estado;
//    }
    public void receberJogada(Jogada jogada) {

        TipoLance tl = meuTabuleiro.receberJogada(jogada);
        if (tl == TipoLance.INICIO_JOGO) {
            this.tabuleiroPanel.montarApenasNomesEEstrategia(meuTabuleiro);
            this.enviarJogadaDeInico(true);

        } else if (tl == TipoLance.COMPLETAR_JOGO) {
            tabuleiroPanel.prepararBotoesCompletarJogo();
        } else if (tl == TipoLance.FIM_DE_JOGO) {
            tabuleiroPanel.mostrarResultadoFinal(!((Lance) jogada).isOponenteVencedor());            
        }
        tabuleiroPanel.montar();
    }

    public void enviarJogada(Lance lance) {
        meuTabuleiro.getT1().setDaVez(false);
        meuTabuleiro.getT2().setDaVez(true);
        tabuleiroPanel.montar();
        //--
        rede.enviarJogada(lance);
    }

    public void setConnectPanel(PanelConnect cp) {
        this.connectPanel = cp;
    }

    public void finalizarPartidaComErro(String message) {

        tabuleiroPanel.connectionLost(message);
        if (!jogoTerminado) {
            tabuleiroPanel.exibirMensagem(message, JOptionPane.ERROR_MESSAGE);
        }
        connectPanel.connectionLost(message);
    }

    public void setTabuleiroPanel(PanelTabuleiro pt) {
        this.tabuleiroPanel = pt;
    }

    /**
     * @return the meuTabuleiro
     */
    public Tabuleiro getMeuTabuleiro() {
        return meuTabuleiro;
    }

    /**
     * @param meuTabuleiro the meuTabuleiro to set
     */
    public void setMeuTabuleiro(Tabuleiro meuTabuleiro) {
        this.meuTabuleiro = meuTabuleiro;
    }

    public void enviarJogadaDeInico(boolean isSegundoTecnico) {

        meuTabuleiro.distribuirValoresIniciais();
        //-
        Lance lance = new Lance((isSegundoTecnico ? TipoLance.FIM_DO_INICIO_DE_JOGO : TipoLance.INICIO_JOGO), meuTabuleiro.getBaralho());
        //-
        //pedir pra tela escolher o esquema tatico
        EsquemaTatico esq = tabuleiroPanel.solicitarEsquemaTatico(meuTabuleiro.getT1().getEsquemas());

        meuTabuleiro.montarEsquema(esq);

        lance.setPosicaoDefesa(meuTabuleiro.getT1().getDefesa());
        lance.setPosicaoMeio(meuTabuleiro.getT1().getMeio());
        lance.setPosicaoAtaque(meuTabuleiro.getT1().getAtaque());

        this.enviarJogada(lance);
    }

    public void trocarEsquema() {
        boolean isCampoVazio = meuTabuleiro.getT1().isCampoVazio();
        String ret = meuTabuleiro.trocarEsquema();
        if (ret == null) {
            if (isCampoVazio) {
                this.enviarTrocaEsquema();
            } else {
                tabuleiroPanel.montar();
                tabuleiroPanel.exibirDialogTrocarEsquema();
            }
        } else {
            tabuleiroPanel.exibirMensagem(ret, JOptionPane.ERROR_MESSAGE);
        }
    }

    public void adicionarJogador(Jogador jogador, TipoPosicao tp) {
        String ret = meuTabuleiro.adicionarJogador(jogador, tp, false);
        if (ret == null) {
            //tabuleiroPanel.montar();             
            TipoLance tl = verificaCondicaoFimDejogo();
            Lance l = new Lance(tl, meuTabuleiro.getBaralho());
            l.setJogadorAdicionado(jogador);
            l.setTipoPosicaoEmQueJogadorFoiAdicionado(tp);
            this.enviarJogada(l);
        } else {
            tabuleiroPanel.exibirMensagem(ret, JOptionPane.ERROR_MESSAGE);
        }
        //enviar jogada, criando lance

    }

    private TipoLance verificaCondicaoFimDejogo() {
        TipoLance tl;
        if (meuTabuleiro.getT1().getQuantidadeEmCampo() == 10) {
            tl = TipoLance.COMPLETAR_JOGO;
        } else {
            tl = TipoLance.ADICIONAR_JOGADOR;
        }
        return tl;
    }

    public void adicionarJogadorSimples(Jogador jogador, TipoPosicao tp, boolean isFimDejogo) {
        String ret = meuTabuleiro.adicionarJogador(jogador, tp, !isFimDejogo);
        if (ret == null) {
            tabuleiroPanel.montar();
            if (meuTabuleiro.getT1().getQuantidadeEmCampo() == 10) {
                this.enviarFimDeJogo();
            }
        } else {
            tabuleiroPanel.exibirMensagem(ret, JOptionPane.ERROR_MESSAGE);
        }
        //enviar jogada, criando lance

    }

    public void substituirJogador(Jogador jogadorNovo, Jogador substituido) {
        TipoPosicao tp = meuTabuleiro.subsituirJogadores(jogadorNovo, substituido);
        Lance l = new Lance(TipoLance.SUBSTITUIR_JOGADOR, meuTabuleiro.getBaralho());
        l.setJogadorAdicionado(jogadorNovo);
        l.setJogadorSubstituido(substituido);
        l.setTipoPosicaoEmQueJogadorFoiAdicionado(tp);
        this.enviarJogada(l);
    }

    public boolean isCampoVazio() {
        return meuTabuleiro.getT1().isCampoVazio();
    }

    public void enviarTrocaEsquema() {
        Lance l = new Lance(TipoLance.TROCAR_ESQUEMA, getMeuTabuleiro().getBaralho());
        l.setPosicaoDefesa(getMeuTabuleiro().getT1().getDefesa());
        l.setPosicaoMeio(getMeuTabuleiro().getT1().getMeio());
        l.setPosicaoAtaque(getMeuTabuleiro().getT1().getAtaque());
        this.enviarJogada(l);
    }

    private void enviarFimDeJogo() {
        Lance l = new Lance(TipoLance.FIM_DE_JOGO, meuTabuleiro.getBaralho());
        l.setPosicaoDefesa(meuTabuleiro.getT1().getDefesa());
        l.setPosicaoMeio(meuTabuleiro.getT1().getMeio());
        l.setPosicaoAtaque(meuTabuleiro.getT1().getAtaque());
        boolean euVenci = meuTabuleiro.tratarFimDeJogo();
        l.setOponenteVencedor(euVenci);
        this.enviarJogada(l);
        setJogoTerminado(true);
        tabuleiroPanel.mostrarResultadoFinal(euVenci);
    }

    public int verificarSePodeSubstituir() {
        return this.meuTabuleiro.verificarSePodeSubstituir();
    }
}
